package com.dev.module_ui_composable.swipe

import android.content.res.Configuration
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt

/**
 * @author zqc
 *
 * 滑动组件
 * @param modifier 修饰符
 * @param enabled 是否启用滑动行为
 * @param swipeStyle 滑动时的手势行为 [SwipeStyle]
 * @param childContent 子组件 @Composable
 * @param primaryContent 主要内容 @Composable
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SwipeLayout(
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    swipeStyle: SwipeStyle = SwipeStyle.EndToStart,
    childContent: @Composable () -> Unit,
    primaryContent: @Composable () -> Unit
) {
    val density = LocalDensity.current
    val childWidth = remember { mutableFloatStateOf(0f) }
    val state = remember {
        AnchoredDraggableState(
            initialValue = DragValue.Start,
//            positionalThreshold = { distance -> distance * 0.5f },
//            velocityThreshold = { with(density) { 50.dp.toPx() } },
//            animationSpec = spring()
        )
    }
    Box(
        modifier = modifier
            .anchoredDraggable(
                state = state ,
                orientation = Orientation.Horizontal,
                enabled = enabled
            )
    ) {
        Box(
            modifier = Modifier
                .onSizeChanged { newSize ->
                    childWidth.floatValue = newSize.width.toFloat()
                    val childWidthPx = with(density) { childWidth.floatValue.toDp().toPx() }
                    val newAnchors = DraggableAnchors {
                        if (swipeStyle == SwipeStyle.EndToStart) {
                            DragValue.Start at 0f
                            DragValue.End at -childWidthPx
                        } else {
                            DragValue.Start at 0f
                            DragValue.End at childWidthPx
                        }
                    }
                    state.updateAnchors(newAnchors)
                }
                .align(getChildAlign(swipeStyle))
        ) {
            childContent()
        }

        Box(
            modifier = Modifier
                .fillMaxWidth()
                .offset { IntOffset(x = state.requireOffset().roundToInt(), y = 0) }
        ) {
            primaryContent()
        }
    }
}

@Composable
private fun getChildAlign(swipeStyle: SwipeStyle) =
    if (swipeStyle == SwipeStyle.EndToStart) Alignment.CenterEnd else Alignment.CenterStart

@Preview(
    name = "自定义滑动组件使用示例",
    uiMode = Configuration.UI_MODE_NIGHT_NO,
    locale = "zh-rCN",
    showBackground = true,
    device = "spec:width=1440px,height=3200px,dpi=560"
)
@Composable
private fun SwipeLayoutSample() {
    SwipeLayout(
        modifier = Modifier
            .fillMaxWidth()
            .height(150.dp)
            .padding(8.dp),
        childContent = {
            Box(
                modifier = Modifier.size(80.dp),
                contentAlignment = Alignment.Center
            ) {
                FilledTonalIconButton(
                    onClick = {},
                    colors = IconButtonDefaults.filledIconButtonColors(
                        containerColor = MaterialTheme.colorScheme.onBackground.copy(0.5f),
                        contentColor = Color.White
                    )
                ) {
                    Icon(
                        imageVector = Icons.Outlined.Delete,
                        contentDescription = null
                    )
                }
            }
        }
    ) {
        Card(
            modifier = Modifier.fillMaxWidth(),
            shape = RoundedCornerShape(12.dp),
            colors = CardDefaults.cardColors(containerColor = Color.White),
            elevation = CardDefaults.cardElevation(3.dp)
        ) {
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(5.dp),
                contentAlignment = Alignment.Center
            ) {
                Text(text = "Swipeable是一种 Compose Material API，可帮助您构建可在各种不同状态间滑动的组件，例如底部动作条、抽屉式导航栏或滑动关闭。")
            }
        }
    }
}